<template>
  <div id="space-rank-analyze">
    <a-card title="空间使用排行" style="width: 100%">
      <v-chart :option="options" style="height: 320px; max-width: 100%;" :loading="loading" />
    </a-card>
  </div>
</template>

<script lang="ts" setup>
import {computed, ref, watchEffect} from 'vue'
import {getSpaceRankAnalyzeUsingPost} from '@/api/spaceAnalyzeController'
import { message } from 'ant-design-vue'
import VChart from "vue-echarts";
import "echarts";
import * as echarts from "echarts"

interface Props {
  queryAll?: boolean
  queryPublic?: boolean
  spaceId?: number
}

const props = withDefaults(defineProps<Props>(), {
  // 默认为false，这样如果单独分析某空间只需要传spaceId
  queryAll: false,
  queryPublic: false,
})

// 接受图表数据
const dataList = ref([])
const loading = ref<boolean>(true) // 默认为true，加载

/**
 * 加载数据
 */
const fetchData = async () => {
  loading.value = true
  const res = await getSpaceRankAnalyzeUsingPost({
    queryAll: props.queryAll,
    queryPublic: props.queryPublic,
    spaceId: props.spaceId,
  })
  if (res.data.code === 0) {
    dataList.value = res.data.data ?? []
  } else {
    message.error('获取数据失败，' + res.data.message)
  }
  // 加载完毕结束加载状态
  loading.value = false
}

/**
 * 监听变量，改变时触发数据的重新加载
 * 只要有任何一个值发生变化，都会重新执行封装的函数
 */
watchEffect(() => {
  fetchData()
})

// 图表内容参数
const options = computed(() => {
  const spaceNames = dataList.value.map((item) => item.spaceName)
  const usageData = dataList.value.map((item) => (item.totalSize / (1024 * 1024)).toFixed(2)) // 转为 MB

  return {
    backgroundColor: 'transparent',
    tooltip: {
      trigger: "axis",
      formatter: (params) => {
        const data = params[0];
        // 空值/异常值处理
        if (data.value === null || data.value === undefined || isNaN(data.value)) {
          return `${data.name}<br/>数据异常`;
        }
        // 零值特殊显示
        if (data.value === 0) {
          return `${data.name}<br/>无使用量`;
        }
        return `${data.name}<br/>使用量: ${data.value} MB`;
      },
      backgroundColor: 'rgba(255,255,255,0.95)',
      borderColor: '#e6ebf5',
      borderWidth: 1,
      textStyle: {
        color: '#606266',
        fontSize: 12
      }
    },
    grid: {
      containLabel: true,
      left: "3%",
      right: "4%",
      bottom: "3%",
      top: '3%',
    },
    dataZoom: [{
      show: dataList.value.length > 10,
      type: 'slider',
      realtime: true,
      startValue: 0,
      endValue: 9,
      yAxisIndex: [0],
      filterMode: 'empty',
      backgroundColor: '#f5f7fa',
      borderColor: '#e6ebf5',
      fillerColor: 'rgba(144,202,249,0.2)',
      handleStyle: {
        color: '#90caf9',
        borderColor: '#64b5f6'
      }
    }],
    xAxis: {
      type: 'value',
      splitLine: {
        show: true,
        lineStyle: {
          type: 'dashed',
          color: '#e6ebf5'
        }
      },
      axisLabel: {
        color: '#909399',
        fontSize: 12
      },
      axisLine: {
        lineStyle: {
          color: '#dcdfe6'
        }
      }
    },
    yAxis: {
      type: 'category',
      inverse: true,
      axisLabel: {
        color: '#606266',
        fontSize: 12,
        formatter: (value) => {
          const maxChar = 8; // 最多显示字符数
          return value.length > maxChar
            ? value.substring(0, maxChar) + '...'
            : value;
        }
      },
      axisTick: { show: false },
      axisLine: { show: false },
      data: (() => {
        return spaceNames
          .map((name, i) => ({
            name,
            value: parseFloat(usageData[i]) || 0
          }))
          .sort((a, b) => b.value - a.value)
          .slice(0, 10)
          .map(item => item.name)
      })()
    },
    series: [{
      type: 'bar',
      barWidth: 14,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
          { offset: 0, color: '#a8edea' },
          { offset: 0.7, color: '#64c3d6' },
          { offset: 1, color: '#3ea1d9' }
        ]),
        borderRadius: [0, 8, 8, 0]
      },
      label: {
        show: true,
        position: 'right',
        color: '#3ea1d9',
        fontSize: 12,
        formatter: ({ value }) => value === 0 ? '空数据' : `${value} MB`
      },
      data: (() => {
        return spaceNames
          .map((name, i) => parseFloat(usageData[i]) || 0)
          .sort((a, b) => b - a)
          .slice(0, 10)
      })()
    }, {
      type: 'pictorialBar',
      symbol: 'circle',
      symbolSize: [8, 8],
      symbolOffset: [18, 0],
      itemStyle: {
        color: '#3ea1d9',
        opacity: 0.6
      },
      tooltip: { show: false },
      data: new Array(10).fill(1) // 装饰元素数量与数据一致
    }]
  }
})

</script>

<style scoped></style>
